package co.edu.eam.iso.view;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import co.edu.eam.iso.enums.ActionEnum;
import co.edu.eam.iso.enums.CharacteristicEnum;
import co.edu.eam.iso.evaluator.Characteristic;
import co.edu.eam.iso.logger.Logger;
import co.edu.eam.iso.util.BigDecimalUtil;


/**
 * Choose characteristics window.
 * 
 * @author Giovanny Ramirez Blandon
 * @version 1.0
 */
public class SelectChrtcs extends JFrame {

	/**
	 * Number of class serialization.
	 */
	private static final long serialVersionUID = 1L;

	private static final int TOTAL_CHARACTERISTICS = 6;

	/**
	 * Content pane.
	 */
	private JPanel contentPane;

	/**
	 * Characteristics to evaluate.
	 */
	private Map<CharacteristicEnum, Characteristic> characteristics;

	private JCheckBox chckPortability;
	private JRadioButton rbAdaptability;
	private JRadioButton rbInstallability;
	private JRadioButton rbCoExistence;
	private JRadioButton rbReplaceability;
	private JCheckBox chckSelectAll;
	private JCheckBox chckUsability;
	private JRadioButton rbLearnability;
	private JRadioButton rbUnderstandability;
	private JRadioButton rbOperability;
	private JRadioButton rbAttractiveness;
	private JRadioButton rbRecoverability;
	private JRadioButton rbFaultTolerance;
	private JRadioButton rbMaturity;
	private JCheckBox chckReliability;
	private JRadioButton rbSuitability;
	private JRadioButton rbSecurity;
	private JRadioButton rbInteroperability;
	private JRadioButton rbAccuracy;
	private JCheckBox chckFunctionality;
	private JCheckBox chckEfficiency;
	private JRadioButton rbTimeBehaviour;
	private JRadioButton rbResourceUtilisation;
	private JCheckBox chckMaintainability;
	private JRadioButton rbAnalyzability;
	private JRadioButton rbChangeability;
	private JRadioButton rbTestability;
	private JRadioButton rbStability;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {	
		try {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		} catch (Exception ex) {
			Logger.getInstance().registrarLog(ex);
		}

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SelectChrtcs frame = new SelectChrtcs();
					frame.setVisible(true);
				} catch (Exception e) {
					Logger.getInstance().registrarLog(e);
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public SelectChrtcs() {
		initialize();
		characteristics = new HashMap<CharacteristicEnum, Characteristic>();
	}

	private void initialize() {
		setTitle("ISO 9126-1 - Características y Sub-características");
		setResizable(false);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(100, 100, 612, 470);
		setJMenuBar(createMenuBar());
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(null);
		setContentPane(contentPane);
		setLocationRelativeTo(null);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				closeWindow();
			}
		});

		JPanel panelCharacteristics = new JPanel();
		panelCharacteristics.setBorder(new TitledBorder(null,
				"Seleccione las caracter\u00EDsticas a evaluar",
				TitledBorder.LEADING, TitledBorder.TOP, null, new Color(59, 59,
						59)));
		panelCharacteristics.setBounds(6, 6, 594, 410);
		contentPane.add(panelCharacteristics);
		panelCharacteristics.setLayout(null);

		panelCharacteristics.add(createPanelFunctionality());
		panelCharacteristics.add(createPanelReliability());
		panelCharacteristics.add(createPanelUsability());
		panelCharacteristics.add(createPanelEfficiency());
		panelCharacteristics.add(createPanelMaintainability());
		panelCharacteristics.add(createPanelPortability());

		JButton btnClose = new JButton("Cerrar");
		btnClose.setBounds(388, 364, 90, 25);
		btnClose.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				closeWindow();
			}
		});

		JButton btnEvaluate = new JButton("Evaluar");
		btnEvaluate.setBounds(480, 364, 90, 25);
		btnEvaluate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				callEvaluatorWindow();
			}
		});

		chckSelectAll = new JCheckBox("Seleccionar todas");
		chckSelectAll.setFont(new Font("SansSerif", Font.BOLD, 12));
		chckSelectAll.setBounds(30, 354, 155, 18);
		chckSelectAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectAllCharacteristics();
			}
		});

		panelCharacteristics.add(chckSelectAll);
		panelCharacteristics.add(btnClose);
		panelCharacteristics.add(btnEvaluate);
	}

	private JMenuBar createMenuBar() {
		JMenuBar menuBar = new JMenuBar();

		JMenu mnFile = new JMenu("Archivo");
		menuBar.add(mnFile);

		JMenuItem mntmExit = new JMenuItem("Cerrar");
		mntmExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				closeWindow();
			}
		});
		mnFile.add(mntmExit);

		JMenu mnTools = new JMenu("Herramientas");
		menuBar.add(mnTools);

		JMenuItem mntmManageMetrics = new JMenuItem("Gestionar métricas");
		mntmManageMetrics.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ManageMetrics manageMetrics = new ManageMetrics(
						SelectChrtcs.this, ActionEnum.MANAGE, null);
				manageMetrics.setVisible(true);
			}
		});
		mnTools.add(mntmManageMetrics);
		
		return menuBar;
	}

	private JPanel createPanelFunctionality() {
		JPanel panelFunctionality = new JPanel();
		panelFunctionality.setLayout(null);
		panelFunctionality.setBorder(new EtchedBorder(EtchedBorder.LOWERED,
				null, null));
		panelFunctionality.setBounds(20, 30, 176, 150);

		rbSuitability = new JRadioButton("Adecuación");
		rbSuitability.setBounds(15, 111, 97, 23);
		rbSuitability.setEnabled(false);
		rbSuitability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbSuitability.setSelected(true);
			}
		});

		rbAccuracy = new JRadioButton("Exactitud");
		rbAccuracy.setBounds(15, 33, 97, 23);
		rbAccuracy.setEnabled(false);
		rbAccuracy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbAccuracy.setSelected(true);
			}
		});

		rbInteroperability = new JRadioButton("Interoperabilidad");
		rbInteroperability.setBounds(15, 59, 134, 23);
		rbInteroperability.setEnabled(false);
		rbInteroperability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbInteroperability.setSelected(true);
			}
		});

		rbSecurity = new JRadioButton("Seguridad");
		rbSecurity.setBounds(15, 85, 97, 23);
		rbSecurity.setEnabled(false);
		rbSecurity.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbSecurity.setSelected(true);
			}
		});

		chckFunctionality = new JCheckBox("Funcionalidad");
		chckFunctionality.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckFunctionality.setBounds(6, 6, 119, 23);
		chckFunctionality.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckFunctionality.isSelected(),
						CharacteristicEnum.FUNCTIONALITY, rbSuitability,
						rbAccuracy, rbInteroperability, rbSecurity);
			}
		});

		panelFunctionality.add(chckFunctionality);
		panelFunctionality.add(rbSuitability);
		panelFunctionality.add(rbAccuracy);
		panelFunctionality.add(rbInteroperability);
		panelFunctionality.add(rbSecurity);

		return panelFunctionality;
	}

	private JPanel createPanelReliability() {
		JPanel panelReliability = new JPanel();
		panelReliability.setLayout(null);
		panelReliability.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		panelReliability.setBounds(208, 30, 175, 150);

		rbMaturity = new JRadioButton("Madurez");
		rbMaturity.setEnabled(false);
		rbMaturity.setBounds(15, 33, 97, 23);
		rbMaturity.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbMaturity.setSelected(true);
			}
		});

		rbFaultTolerance = new JRadioButton("Tolerancia a fallos");
		rbFaultTolerance.setEnabled(false);
		rbFaultTolerance.setBounds(15, 59, 134, 23);
		rbFaultTolerance.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbFaultTolerance.setSelected(true);
			}
		});

		rbRecoverability = new JRadioButton("Recuperabilidad");
		rbRecoverability.setEnabled(false);
		rbRecoverability.setBounds(15, 85, 128, 23);
		rbRecoverability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbRecoverability.setSelected(true);
			}
		});

		chckReliability = new JCheckBox("Fiabilidad");
		chckReliability.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckReliability.setBounds(6, 6, 119, 23);
		chckReliability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckReliability.isSelected(),
						CharacteristicEnum.RELIABILITY, rbMaturity,
						rbFaultTolerance, rbRecoverability);
			}
		});

		panelReliability.add(chckReliability);
		panelReliability.add(rbMaturity);
		panelReliability.add(rbFaultTolerance);
		panelReliability.add(rbRecoverability);

		return panelReliability;
	}

	private JPanel createPanelUsability() {
		JPanel panelUsability = new JPanel();
		panelUsability.setLayout(null);
		panelUsability.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		panelUsability.setBounds(395, 30, 175, 150);

		rbUnderstandability = new JRadioButton("Comprensabilidad");
		rbUnderstandability.setEnabled(false);
		rbUnderstandability.setBounds(15, 59, 134, 23);
		rbUnderstandability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbUnderstandability.setSelected(true);
			}
		});

		rbLearnability = new JRadioButton("Aprendibilidad");
		rbLearnability.setEnabled(false);
		rbLearnability.setBounds(15, 33, 129, 23);
		rbLearnability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbLearnability.setSelected(true);
			}
		});

		rbOperability = new JRadioButton("Operabilidad");
		rbOperability.setEnabled(false);
		rbOperability.setBounds(15, 85, 97, 23);
		rbOperability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbOperability.setSelected(true);
			}
		});

		rbAttractiveness = new JRadioButton("Atractividad");
		rbAttractiveness.setEnabled(false);
		rbAttractiveness.setBounds(15, 111, 97, 23);
		rbAttractiveness.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbAttractiveness.setSelected(true);
			}
		});

		chckUsability = new JCheckBox("Usabilidad");
		chckUsability.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckUsability.setBounds(6, 7, 107, 23);
		chckUsability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckUsability.isSelected(),
						CharacteristicEnum.USABILITY, rbUnderstandability,
						rbLearnability, rbOperability, rbAttractiveness);
			}
		});

		panelUsability.add(chckUsability);
		panelUsability.add(rbUnderstandability);
		panelUsability.add(rbLearnability);
		panelUsability.add(rbOperability);
		panelUsability.add(rbAttractiveness);

		return panelUsability;
	}

	private JPanel createPanelEfficiency() {
		JPanel panelEfficiency = new JPanel();
		panelEfficiency.setLayout(null);
		panelEfficiency.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		panelEfficiency.setBounds(20, 192, 175, 150);

		rbTimeBehaviour = new JRadioButton("Tiempo de respuesta");
		rbTimeBehaviour.setEnabled(false);
		rbTimeBehaviour.setBounds(15, 33, 156, 23);
		rbTimeBehaviour.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbTimeBehaviour.setSelected(true);
			}
		});

		rbResourceUtilisation = new JRadioButton("Utilización de recursos");
		rbResourceUtilisation.setEnabled(false);
		rbResourceUtilisation.setBounds(15, 59, 156, 23);
		rbResourceUtilisation.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbResourceUtilisation.setSelected(true);
			}
		});

		chckEfficiency = new JCheckBox("Eficiencia");
		chckEfficiency.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckEfficiency.setBounds(6, 7, 95, 23);
		chckEfficiency.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckEfficiency.isSelected(),
						CharacteristicEnum.EFFICIENCY, rbTimeBehaviour,
						rbResourceUtilisation);
			}
		});

		panelEfficiency.add(chckEfficiency);
		panelEfficiency.add(rbTimeBehaviour);
		panelEfficiency.add(rbResourceUtilisation);

		return panelEfficiency;
	}

	private JPanel createPanelMaintainability() {
		JPanel panelMaintainability = new JPanel();
		panelMaintainability.setLayout(null);
		panelMaintainability.setBorder(new EtchedBorder(EtchedBorder.LOWERED,
				null, null));
		panelMaintainability.setBounds(208, 192, 175, 150);

		rbAnalyzability = new JRadioButton("Facilidad de análisis");
		rbAnalyzability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbAnalyzability.setSelected(true);
			}
		});
		rbAnalyzability.setEnabled(false);
		rbAnalyzability.setBounds(15, 33, 139, 23);

		rbChangeability = new JRadioButton("Facilidad de cambio");
		rbChangeability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbChangeability.setSelected(true);
			}
		});
		rbChangeability.setEnabled(false);
		rbChangeability.setBounds(15, 59, 139, 23);

		rbStability = new JRadioButton("Estabilidad");
		rbStability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbStability.setSelected(true);
			}
		});
		rbStability.setEnabled(false);
		rbStability.setBounds(15, 111, 97, 23);

		rbTestability = new JRadioButton("Facilidad de prueba");
		rbTestability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbTestability.setSelected(true);
			}
		});
		rbTestability.setEnabled(false);
		rbTestability.setBounds(15, 85, 139, 23);

		chckMaintainability = new JCheckBox("Mantenibilidad");
		chckMaintainability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckMaintainability.isSelected(),
						CharacteristicEnum.MAINTAINABILITY, rbAnalyzability,
						rbChangeability, rbStability, rbTestability);
			}
		});
		chckMaintainability.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckMaintainability.setBounds(6, 7, 139, 23);

		panelMaintainability.add(chckMaintainability);
		panelMaintainability.add(rbAnalyzability);
		panelMaintainability.add(rbChangeability);
		panelMaintainability.add(rbStability);
		panelMaintainability.add(rbTestability);

		return panelMaintainability;
	}

	private JPanel createPanelPortability() {
		JPanel panelPortability = new JPanel();
		panelPortability.setLayout(null);
		panelPortability.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		panelPortability.setBounds(395, 192, 175, 150);

		rbAdaptability = new JRadioButton("Adaptabilidad");
		rbAdaptability.setEnabled(false);
		rbAdaptability.setBounds(15, 33, 121, 23);
		rbAdaptability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbAdaptability.setSelected(true);
			}
		});

		rbInstallability = new JRadioButton("Instalabilidad");
		rbInstallability.setEnabled(false);
		rbInstallability.setBounds(16, 59, 120, 23);
		rbInstallability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbInstallability.setSelected(true);
			}
		});

		rbCoExistence = new JRadioButton("Co-Existencia");
		rbCoExistence.setEnabled(false);
		rbCoExistence.setBounds(16, 85, 120, 23);
		rbCoExistence.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbCoExistence.setSelected(true);
			}
		});

		rbReplaceability = new JRadioButton("Reemplazabilidad");
		rbReplaceability.setEnabled(false);
		rbReplaceability.setBounds(16, 111, 136, 23);
		rbReplaceability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				rbReplaceability.setSelected(true);
			}
		});

		chckPortability = new JCheckBox("Portabilidad");
		chckPortability.setFont(new Font("Tahoma", Font.BOLD, 14));
		chckPortability.setBounds(6, 7, 107, 23);
		chckPortability.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectCharacteristic(chckPortability.isSelected(),
						CharacteristicEnum.PORTABILITY, rbAdaptability,
						rbInstallability, rbCoExistence, rbReplaceability);
			}
		});

		panelPortability.add(chckPortability);
		panelPortability.add(rbAdaptability);
		panelPortability.add(rbInstallability);
		panelPortability.add(rbCoExistence);
		panelPortability.add(rbReplaceability);

		return panelPortability;
	}

	private void selectAllCharacteristics() {
		boolean selected = chckSelectAll.isSelected();

		chckFunctionality.setSelected(selected);
		chckReliability.setSelected(selected);
		chckEfficiency.setSelected(selected);
		chckUsability.setSelected(selected);
		chckPortability.setSelected(selected);
		chckMaintainability.setSelected(selected);

		selectCharacteristic(selected, CharacteristicEnum.FUNCTIONALITY,
				rbSuitability, rbAccuracy, rbInteroperability,
				rbSecurity);

		selectCharacteristic(selected, CharacteristicEnum.RELIABILITY,
				rbMaturity, rbFaultTolerance, rbRecoverability);

		selectCharacteristic(selected, CharacteristicEnum.USABILITY,
				rbUnderstandability, rbLearnability, rbOperability,
				rbAttractiveness);

		selectCharacteristic(selected, CharacteristicEnum.EFFICIENCY,
				rbTimeBehaviour, rbResourceUtilisation);

		selectCharacteristic(selected, CharacteristicEnum.MAINTAINABILITY,
				rbAnalyzability, rbChangeability, rbStability,
				rbTestability);

		selectCharacteristic(selected, CharacteristicEnum.PORTABILITY,
				rbAdaptability, rbInstallability, rbCoExistence,
				rbReplaceability);
	}

	private void selectCharacteristic(boolean selected,
			CharacteristicEnum characteristicEnum,
			JRadioButton... rbCharacteristics) {	
		if (selected) {
			addCharacteristic(characteristicEnum);
		} else {
			removeCharacteristic(characteristicEnum);
		}

		for (JRadioButton subCharacteristics : rbCharacteristics) {
			subCharacteristics.setSelected(selected);
			subCharacteristics.setEnabled(selected);
		}
		
		boolean selectedAll = characteristics.size() == TOTAL_CHARACTERISTICS;
		chckSelectAll.setSelected(selectedAll);
	}

	private void addCharacteristic(CharacteristicEnum characteristicEnum) {
		characteristics.put(characteristicEnum, null);
	}

	private void removeCharacteristic(CharacteristicEnum characteristicEnum) {
		characteristics.remove(characteristicEnum);
	}

	private void closeWindow() {
		int option = JOptionPane.showConfirmDialog(this,
				"¿Cerrar la aplicación?", "Mensaje de confirmación",
				JOptionPane.YES_NO_OPTION);

		if (JOptionPane.YES_OPTION == option) {
			System.exit(0);
		}
	}

	private void callEvaluatorWindow() {
		if (!characteristics.isEmpty()) {
			calculateWeight();
			EvaluateChrtcs evaluateChrtcs = new EvaluateChrtcs(this,
					characteristics);
			evaluateChrtcs.setVisible(true);
		} else {
			JOptionPane.showMessageDialog(this,
					"Debe seleccionar al menos 1 característica",
					"Mensaje de error", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void calculateWeight() {
		for (Entry<CharacteristicEnum, Characteristic> entry : characteristics
				.entrySet()) {
			Characteristic characteristic = new Characteristic();
			characteristic.setCharacteristicEnum(entry.getKey());		
			BigDecimal weight = new BigDecimal(100.00 / characteristics.size());
			characteristic.setWeight(BigDecimalUtil.round(weight, 2, RoundingMode.HALF_UP));
			entry.setValue(characteristic);
		}
	}
}
